<template>
  <div class="TestStep box-border wh-full">
    <n-spin :show="show" class="wh-full">
      <div
        v-if="appStore.isDeep"
        class="steps box-border h-176 w-100% flex flex-shrink-0 items-center px-80"
      >
        <DeepItem v-for="(item, index) in stepData" :key="index" :num="index + 1" v-bind="item" />
      </div>
      <div v-else class="steps box-border h-146 w-100% flex flex-shrink-0 items-center px-80">
        <LightItem v-for="(item, index) in stepData" :key="index" :num="index + 1" v-bind="item" />
      </div>
      <BoxContent v-if="appStore.isDeep" padding="0">
        <n-scrollbar ref="$scrollbar" class="box-border w-full">
          <div class="w-full flex-col flex-1 px-52 pt-32">
            <slot />
          </div>
        </n-scrollbar>
        <div id="step-control" class="box-border w-100% flex-shrink-0 pb-32"></div>
      </BoxContent>
      <div v-else class="box-border w-full flex-col flex-1 overflow-hidden rounded-12 bg-#FFF">
        <n-scrollbar ref="$scrollbar" class="box-border w-full">
          <div class="w-full flex-col flex-1 px-52 pt-32">
            <slot />
          </div>
        </n-scrollbar>
        <div id="step-control" class="box-border w-100% flex-shrink-0 pb-32"></div>
      </div>
    </n-spin>
  </div>
</template>
<script setup lang="jsx">
import { useAppStore } from '@/store'
import topFlag01 from '@/assets/images/top-flag-01.png'
import topFlag02 from '@/assets/images/top-flag-02.png'
import btmFlag01 from '@/assets/images/btm-flag-01.png'
import btmFlag02 from '@/assets/images/btm-flag-02.png'
import report01 from '@/assets/images/report-01.png'
import report02 from '@/assets/images/report-02.png'
import deepBranch from '@/assets/images/deep-branch.png'
import deepBranchActive from '@/assets/images/deep-branch-active.png'
defineOptions({
  name: 'TestStep',
})
const appStore = useAppStore()
const step = defineModel({
  type: Number,
  default: 1,
})
const show = defineModel('show', {
  type: Boolean,
  default: false,
})
const props = defineProps({
  // static|dynamic
  type: {
    type: String,
    default: 'static',
  },
  size: {
    type: Number,
    default: 40,
  },
  isEvaluate: {
    type: Boolean,
    default: true,
  },
})
const isStatic = computed(() => props.type === 'static')
const stepData = [
  { text: '被测对象选择' },
  { text: '测试方案匹配' },
  { text: '测试科目设计' },
  { text: '测试表单生成' },
  { text1: '静态测试数据集生成', text2: '动态测试任务生成', flex: 1.1 },
  { text1: '静态测试执行', text2: '动态测试执行', flex: 1.1 },
  { text: '评估设置确认' },
  { text: '评估报告' },
]
const LightItem = ({ num, text, text1, text2, flex = 1 }) => {
  const isActive = num <= step.value
  return (
    <div
      class={[
        'light-line',
        isActive ? 'active' : '',
        num === step.value ? 'current' : '',
        num >= 7 && !props.isEvaluate ? 'disabled' : '',
      ]}
      style={{ flex: num === 8 ? 0 : flex }}
    >
      <div class="label" style={{ width: `${props.size}px`, height: `${props.size}px` }}>
        <div v-show={num != 8} class="num">
          {`${num}`.padStart(2, '0')}
        </div>
        <img v-show={num == 8} src={isActive || !props.isEvaluate ? report02 : report01} />
        <div v-show={text} class="text">
          {text}
        </div>
      </div>
      <div v-show={text1} class={['top flag', isStatic.value ? 'type' : '']}>
        <img src={isActive && isStatic.value ? topFlag02 : topFlag01} />
        <div class="word">{text1}</div>
        <div v-show={num === 5} class="tie"></div>
      </div>
      <div v-show={text2} class={['btm flag', !isStatic.value ? 'type' : '']}>
        <img src={isActive && !isStatic.value ? btmFlag02 : btmFlag01} />
        <div class="word">{text2}</div>
        <div v-show={num === 5} class="tie"></div>
      </div>
    </div>
  )
}
const DeepBranch = ({ active = false, type = 'tl' }) => {
  if (type === 'bl') {
    return (
      <img
        class="block h-45 w-42"
        style="transform: rotateX(180deg);"
        src={active ? deepBranchActive : deepBranch}
      />
    )
  } else if (type === 'tr') {
    return (
      <img
        class="block h-45 w-42"
        style="transform: rotateY(180deg);"
        src={active ? deepBranchActive : deepBranch}
      />
    )
  } else if (type === 'br') {
    return (
      <img
        class="block h-45 w-42"
        style="transform: rotate(180deg);"
        src={active ? deepBranchActive : deepBranch}
      />
    )
  } else {
    return <img class="h-45 w-42" src={active ? deepBranchActive : deepBranch} />
  }
}
const DeepLine = ({ point = true, active = false }) => {
  return <div class={['deep-line', point ? 'point' : '', active ? 'active' : '']}></div>
}
const DeepStart = ({ active = false }) => {
  return (
    <div class="flex flex-1 items-center">
      <DeepLine active={active} class="flex-1" />
      <div class="ml--1 flex-col flex-shrink-0 justify-center">
        <DeepBranch active={active && isStatic.value} type="tl" class="translate-y-1" />
        <DeepBranch active={active && !isStatic.value} type="bl" />
      </div>
      <div class="h-89 flex-col flex-1 justify-between">
        <DeepLine active={active && isStatic.value} class="w-full" point={false} />
        <DeepLine active={active && !isStatic.value} class="w-full" point={false} />
      </div>
    </div>
  )
}
const DeepEnd = ({ active = false }) => {
  return (
    <div class="flex flex-1 items-center">
      <div class="h-90 flex-col flex-1 justify-between">
        <DeepLine active={active && isStatic.value} class="w-full" />
        <DeepLine active={active && !isStatic.value} class="w-full" />
      </div>
      <div class="flex-col flex-shrink-0 justify-center">
        <DeepBranch active={active && isStatic.value} type="tr" />
        <DeepBranch active={active && !isStatic.value} type="br" />
      </div>
      <DeepLine active={active} class="ml--1 flex-1" point={false} />
    </div>
  )
}
const DeepBox = ({ num, text, active = false, pr = false }) => {
  return (
    <div class={['deep-box', active ? 'active' : '']}>
      <div class="deep-num">{`${num}`.padStart(2, '0')}</div>
      <div class="deep-content" style={{ paddingRight: pr ? '26px !important' : 'auto' }}>
        {text}
      </div>
    </div>
  )
}
const DeepItem = ({ num, text, text1, text2 }) => {
  const isActive = num <= step.value
  return (
    <div
      class={[
        'deep-item',
        [1, 5, 7].includes(num) ? '' : 'flex-1',
        num === 5 ? 'flex-grow-1.2 flex-shrink-0 flex-basis-1% min-w-210' : '',
        num === 7 ? 'flex-grow-1 flex-shrink-0 flex-basis-1% min-w-160' : '',
        !props.isEvaluate && num >= 7 ? 'opacity-40' : '',
      ]}
    >
      {/* 常规线 */}
      <DeepLine active={isActive} v-show={[2, 3, 4, 8].includes(num)} class="flex-1" />
      {/* 分开线 */}
      <DeepStart active={isActive} v-show={num === 5} />
      {/* 合并线 */}
      <DeepEnd active={isActive} v-show={num === 7} />
      {/* 单个tag */}
      <DeepBox active={isActive} v-show={text} num={num} text={text} />
      {/* 多个tag */}
      <div
        v-show={!text}
        class={['h-120 flex-col justify-between flex-shrink-0', num === 6 ? 'flex-1' : '']}
      >
        <div class="flex items-center">
          <DeepLine active={isActive && isStatic.value} v-show={num === 6} class="flex-1" />
          <DeepBox active={isActive && isStatic.value} num={num} text={text1} />
        </div>
        <div class="flex items-center">
          <DeepLine active={isActive && !isStatic.value} v-show={num === 6} class="flex-1" />
          <DeepBox active={isActive && !isStatic.value} num={num} text={text2} pr={num === 5} />
        </div>
      </div>
    </div>
  )
}
const $scrollbar = ref(null)
function scrollTo(...arg) {
  return $scrollbar.value.scrollTo(...arg)
}
defineExpose({
  scrollTo,
})
</script>
<style lang="scss" scoped>
@mixin quadrangle($color, $size, $width) {
  background: linear-gradient(to top, $color, $color) left top no-repeat,
    //上左
    linear-gradient(to right, $color, $color) left top no-repeat,
    //左上
    linear-gradient(to left, $color, $color) right top no-repeat,
    //上右
    linear-gradient(to bottom, $color, $color) right top no-repeat,
    //上右
    linear-gradient(to left, $color, $color) left bottom no-repeat,
    //下左
    linear-gradient(to bottom, $color, $color) left bottom no-repeat,
    //左下
    linear-gradient(to top, $color, $color) right bottom no-repeat,
    //下右
    linear-gradient(to left, $color, $color) right bottom no-repeat; //右下
  background-size: $width $size, $size $width, $width $size, $size $width;
}
:deep(.n-spin-content) {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
}
:deep() {
  .light-line {
    height: 12px;
    background: #fff;
    position: relative;
    .label {
      display: flex;
      align-items: center;
      justify-content: center;
      position: absolute;
      z-index: 100;
      top: 50%;
      left: 0;
      transform: translate(-50%, -50%);
      box-sizing: border-box;
      border: 3px solid #ffffff;
      background: #edf2ff;
      border-radius: 50%;
      .num {
        font-family: GalanoGrotesque;
        font-weight: 600;
        font-size: 16px;
        color: #9eb4c2;
        line-height: 20px;
      }
      .text {
        position: absolute;
        top: calc(100% + 12px);
        left: 50%;
        transform: translateX(-50%);
        white-space: nowrap;
        color: #817e92;
        font-size: 12px;
        font-weight: 400;
      }
    }
    .flag {
      position: absolute;
      height: 50px;
      width: 100%;
      display: flex;
      flex-wrap: nowrap;
      left: 0;
      z-index: 4;
      &.top {
        bottom: 0;
        align-items: flex-start;
      }
      &.btm {
        top: 0;
        align-items: flex-end;
      }
      .word {
        white-space: nowrap;
        color: #817e92;
        font-size: 12px;
        font-weight: 400;
        line-height: 12px;
        padding-left: 12px;
      }
      .tie {
        flex: 1;
        height: 12px;
        display: flex;
        align-items: center;
        margin: 0 10px;
        &::before {
          content: '';
          width: 100%;
          height: 1px;
          background: #c5d2e0;
        }
      }
    }
    &.active {
      background: #6d61e3;
      &.current {
        background: #fff;
        &::before {
          content: '';
          display: block;
          width: 50%;
          height: 100%;
          background: #6d61e3;
          border-radius: 0 10px 10px 0;
        }
      }
      .label {
        background: #6d61e3;
        box-shadow: 0px 2px 9px 0px rgba(109, 97, 227, 0.39);
        .num {
          color: #ffffff;
        }
        .text {
          font-weight: 500;
          color: #140d35;
        }
      }
      .type {
        .word {
          font-weight: 500;
          color: #140d35;
        }
        .tie::before {
          background: #6d61e3;
        }
      }
    }
    &.disabled {
      background: #dcd9f8;
      .label {
        background: #dcd9f8;
        .num {
          color: #ffffff;
        }
        .text {
          font-weight: 400;
          color: #817e92;
        }
      }
    }
  }
  .deep-item {
    display: flex;
    align-items: center;
    .deep-box {
      flex-shrink: 0;
      border: 1px solid #3198e452;
      border-radius: 1px;
      padding: 3px 4px;
      position: relative;
      @include quadrangle(#3198e475, 3px, 1px);
      .deep-content {
        box-shadow: inset 0px 0px 9px 0px #3198e4;
        border-radius: 1px;
        color: #2ba1ff;
        height: 28px;
        line-height: 28px;
        padding: 0 12px;
        font-weight: 500;
      }
      .deep-num {
        box-sizing: border-box;
        padding-left: 5px;
        width: 36px;
        height: 20px;
        line-height: 20px;
        background: url(@/assets/images/deep-step-bg.png) center no-repeat;
        position: absolute;
        left: 4px;
        bottom: calc(100% + 4px);
        color: #3198e4;
        font-size: 12px;
      }
      &.active {
        border: 1px solid #5fe9fc99;
        @include quadrangle(#5fe9fc, 3px, 1px);
        .deep-content {
          box-shadow: inset 0px 0px 9px 0px #68e5f7;
          color: #51e6fb;
          font-weight: bold;
        }
        .deep-num {
          background: url(@/assets/images/deep-step-bg-active.png) center no-repeat;
          color: #5fe9fc;
        }
      }
    }
    .deep-line {
      height: 1px;
      background: #3198e47d;
      position: relative;
      &.point::before {
        content: '';
        display: block;
        height: 5px;
        width: 5px;
        position: absolute;
        z-index: 10;
        left: -2px;
        top: -2px;
        background: #3198e4;
        border-radius: 50%;
      }
      &.active {
        background: #5fe9fc;
        &.point::before {
          background: #5fe9fc;
        }
      }
    }
  }
}
</style>
